package ts;

import java.util.HashMap;
import java.util.Vector;

public class nkSystem {

	private static Clase SYSTEM;
	private static HashMap<String,Metodo> metodos;
	
	public static String out = "";
	
	private static void gen(String et, String s) {
		//System.out.print(et + ": ");
		//System.out.println(s);
		out = out + et + ": " + s + "\n";
	}

	private static void gen(String s) {
		//System.out.println(s);
		out = out + s + "\n";
	}
	
	public static Clase get() {
		create();
		return SYSTEM;
	}
	
	public static void create() {
		SYSTEM = new Clase("System",true);
		SYSTEM.definida = true;		
		SYSTEM.constructor = TablaDeClases.CONSTRUCTOR_VACIO;
		metodos = new HashMap<String,Metodo>();
		SYSTEM.metodos = metodos;
		addRead();
		addPrintB();
		addPrintC();
		addPrintI();
		addPrintS();
		addPrintln();
		addPrintBln();
		addPrintCln();
		addPrintIln();
		addPrintSln();
		SYSTEM.allMetodos = metodos;
		addVT();
	}
	
	private static void addRead() {
		Vector<Variable> atributos = new Vector<Variable>();
		Metodo m = new Metodo("int","read",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen("\n.CODE");
		gen(m.etiqueta,"NOP");
		
	}
	
	private static void addPrintB() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("b", "boolean", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printB",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("BPRINT");
		
		gen("STOREFP");
		gen("RET 2");

	}
	
	private static void addPrintC() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("c", "char", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printC",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("CPRINT");
		
		gen("STOREFP");
		gen("RET 2");
	}
	
	private static void addPrintI() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("i", "int", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printI",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("IPRINT");
		
		gen("STOREFP");
		gen("RET 2");
	}
	
	private static void addPrintS() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("s", "String", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printS",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("SPRINT");
		
		gen("STOREFP");
		gen("RET 2");
	}
	
	private static void addPrintln() {
		Vector<Variable> atributos = new Vector<Variable>();
		Metodo m = new Metodo("void","println",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("PRNLN");
		
		gen("STOREFP");
		gen("RET 1");
	}
	
	private static void addPrintBln() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("b", "boolean", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printBln",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("BPRINT");
		gen("PRNLN");
		
		gen("STOREFP");
		gen("RET 2");
	}
	
	private static void addPrintCln() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("c", "char", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printCln",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("CPRINT");
		gen("PRNLN");
		
		gen("STOREFP");
		gen("RET 2");
	}
	
	private static void addPrintIln() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("i", "int", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printIln",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("IPRINT");
		gen("PRNLN");
		
		gen("STOREFP");
		gen("RET 2");
	}
	
	private static void addPrintSln() {
		Vector<Variable> atributos = new Vector<Variable>();
		Variable v = new Variable("s", "String", false);
		v.offset = 4; //ver
		atributos.add(v);
		Metodo m = new Metodo("void","printSln",atributos);
		m.offset = metodos.size();
		metodos.put(m.name,m);
		m.etiqueta = "l"+m.name+"$System";
		
		gen(m.etiqueta,"NOP");
		gen("LOADFP");
		gen("LOADSP");
		gen("STOREFP");	
		
		gen("LOAD "+v.offset);
		gen("SPRINT");
		gen("PRNLN");
		
		gen("STOREFP");
		gen("RET 2");
	}
	
	private static void addVT() {
		gen("\n; clase System");
		gen(".DATA");
		
		int n = metodos.size();
		
		String cod = "DW ";
		String sep = "";
		String a[] = new String[n];
		for (Metodo m : metodos.values())
			a[m.offset] = m.etiqueta;
		for (int i = 0; i < n; i++) {
			cod = cod + sep + a[i];
			sep = " , ";
		}
		gen("VTSystem", cod);	
		
	}
	
}
